#!/usr/bin/env python
# -*- coding: utf-8 -*-
import matplotlib.pyplot as plt
import numpy as np
import random

class Point(object):
	def __init__(self, x, y):
		self.x = float(x)
		self.y = float(y)
	
class SDT(object):
	def __init__(self, deltaE):    # deltaE 建议设置为量程的千分之一
		self.currentData = None
		self.lastReadData = None
		self.lastStoredData = None
		self.deltaE = deltaE
		self.resetGate()
	
	def resetGate(self):
		self.up_gate = float("-inf")
		self.down_gate = float("inf")
		
	def check(self, data):
		if isinstance(data, tuple) or isinstance(data, tuple):
			self.currentData = Point(data[0], data[1])
		elif isinstance(data, dict):
			self.currentData = Point(data["x"], data["y"])
		else:
			self.currentData = data
			
		if self.lastStoredData == None:
			self.lastStoredData = self.currentData
			return self.lastStoredData.x, self.lastStoredData.y
		if self.lastReadData == None: self.lastReadData = self.currentData
		if self.currentData.x == self.lastStoredData.x:
			return None, None
		now_up = (self.currentData.y - self.lastStoredData.y - self.deltaE)/(self.currentData.x - self.lastStoredData.x)
		now_down = (self.currentData.y - self.lastStoredData.y + self.deltaE)/(self.currentData.x - self.lastStoredData.x)
		if now_up > self.up_gate:
			self.up_gate = now_up
		if now_down < self.down_gate:
			self.down_gate = now_down
		if self.up_gate >= self.down_gate:
			self.lastStoredData = self.lastReadData
			self.lastReadData = self.currentData
			self.up_gate = (self.currentData.y - self.lastStoredData.y - self.deltaE)/(self.currentData.x - self.lastStoredData.x)
			self.down_gate = (self.currentData.y - self.lastStoredData.y + self.deltaE)/(self.currentData.x - self.lastStoredData.x)
			return self.lastStoredData.x, self.lastStoredData.y
		else:
			self.lastReadData = self.currentData
		return None, None

def compress(s, x, y):
	"""
	使用SDT进行单个数据的筛选，进行压缩
	:return:
	"""
	x_data = []
	y_data = []
	for i in range(len(x)):
		xi = x[i]
		yi = y[i]
		dx, dy = s.check((xi, yi))
		if dx != None and dy != None:
			x_data.append(dx)
			y_data.append(dy)
			#print("需要的存储数据点为(%.2f,%.2f)" % (dx, dy))
		else:
			pass
	return x_data, y_data

if __name__ == '__main__':
	scale = 10
	deltaE = 0.01*scale
	x = np.arange(0, 2*np.pi, 0.01)
	y = np.sinc(x)*scale
	xx = [t for t in x]
	yy = [t+(([-1, 1]+[0]*98)[random.randint(0, 100) % 100])*scale*min(0.02, random.random()) for t in y]
	s = SDT(deltaE)
	x = xx
	y = yy
	cx, cy = compress(s, x, y)
	cx.append(x[-1])
	cy.append(y[-1])
	plt.grid(True, linewidth="0.5")
	plt.plot(x, y, '-', color='blue', label='true')
	plt.xlabel("x")
	plt.ylabel("y")
	plt.plot(cx, cy, "*", color='green', label='compress')
	plt.show()